<?php
class ReviewerHelper{

	protected static $lastError = '';

	/**
	  * 写入所有审核人，做为以后依次判断的依据
	  * 在相关记录(class&related_id)首次创建时增加
	  * 审批人及顺序设置在部门信息里(reviewers)，$dept_id即部门ID
	  */
	public static function expand($class, $related_id, $dept_id, $type2=0){
		if(!self::validClass($class)){
			return self::setError('未知类型');
		}

		if(Db::get('Reviewer')->count()->where(array('class'=>$class, 'related_id'=>$related_id))->getCol() >0){
			return self::setError('相同审批记录已存在');
		}
		$rev = DeptHelper::getReviewers($dept_id, $type2);
		if(!$rev){
			return self::setError('此部门未设置审批人');
			//todo: 没有设置审批人，记录自动通过？
		}

		$trans = Db::get()->trans();
		$trans->on();
		foreach(explode(',', $rev) as $user_id){
			if(!Reviewer::add(array(
					'class' => $class,
					'related_id' => $related_id, 
					'user_id' => $user_id,
					'addtime' => 0,
					'pass' => Reviewer::AUDIT_NONE, //未审
				))){
				$trans->rollback();
				return self::setError('设置审批人信息出错');
			};
		}
		$trans->commit();
		return true;
	}
	
	/**
	 * 修改单据时，保存审批状态并删除当前审批信息，待新建审批状态；
	 */
	public static function backupAndClean($class, $related_id){
		$list = self::getList($class, $related_id);
		$func = function($row){
			static $keys = '';
			if(!$keys) $keys = array_flip(array('user_id','addtime','pass','remark','track','user_name'));
			return array_intersect_key($row, $keys);
		};
		$brief = array_map($func, $list);
		$res = Db::get('ReviewerBack')->insert(array(
				'class'	=> $class,
				'related_id' => $related_id,
				'addtime'	=> time(),
				'brief'	=> json_encode($brief),
			))->exec();
		if($res && Db::get('ReviewerBack')->insertId()){
			return Db::get('Reviewer')->delete()->where(array(
				'class'	=> $class,
				'related_id' => $related_id,
				))->exec() && Db::get('Reviewer')->affectedRows();
		}
		else{
			return false;
		}
	}
	
	/**
	 * 取审批备份记录
	 */
	public static function getBackups($class, $related_id){
		$list = Db::get('ReviewerBack')->select()->where(array(
					'class'	=> $class,
					'related_id' => $related_id,
				))->order('id ASC')->getAll();
		$func = function($row){
			$row['brief'] = json_decode($row['brief'], true);
			return $row;
		};
		return $list ? array_map($func, $list) : array();
	}

	/**
	  * 取当前审批人ID
	  */
	public static function getCursor($class, $related_id){
		if(!self::validClass($class)){
			return self::setError('未知类型');
		}
		return Db::get('Reviewer')->select('user_id')
					->where(array('class'=>$class,'related_id'=>$related_id, 'pass'=>Reviewer::AUDIT_NONE))
					->order('id ASC')->limit(1)->getCol();
	}

	/**
	  * 添加审批记录
	  * @param bool $pass 成功/失败
	  */
	public static function audit($class, $related_id, $user_id, $pass=true, $remark=''){
		if(self::getCursor($class, $related_id)!=$user_id){
			return self::setError('不是审批人或目前无权操作');
		}
		$r = Db::get('Reviewer')->update(array('pass'=>$pass? Reviewer::AUDIT_PASS : Reviewer::AUDIT_FAIL,
											   'addtime'=>time(),
												'track' => UserTrack::get(),
											   'remark'=>FilterHelper::strip($remark)))
					->where(array('class'=>$class,'related_id'=>$related_id,'user_id'=>$user_id))
					->exec();
		if(!$r){
			return self::setError('保存记录失败');
		}
		elseif(!$pass){
			//当前用户审批未通过，修改原始记录
			if(!self::updateFlow($class, $related_id, Reviewer::AUDIT_FAIL)){
				return self::setError('修改原始记录失败 2');
			}
		}
		elseif(self::haspass($class, $related_id)){
			//若全部审批都成功，修改原始记录审核状态 audit_flow
			if(!self::updateFlow($class, $related_id, Reviewer::AUDIT_PASS)){
				if(!self::$lastError) self::setError('修改原始记录失败 1');
				return false;
			}
		}
		return true;
	}

	/**
	  * 检查某审批是否通过
	  * 按pass汇总，若记录数为一且值为1(通过审核)，表示全部通过审核了
	  */
	public static function haspass($class, $related_id){
		$rows = Db::get('Reviewer')->select('pass')
					->where(array('class'=>$class,'related_id'=>$related_id))
					->group('pass')->getCols();
		if(count($rows)==1 && $rows[0]==1){
			return true;
		}
		return false;
	}
        
        /**
	  * 检查某审批是否没有通过
	  * 按pass汇总，若记录数中值为2的为没有通过
	  */
	public static function nohaspass($class, $related_id){
		$rows = Db::get('Reviewer')->select('pass')
					->where(array('class'=>$class,'related_id'=>$related_id))
					->order('pass desc')->group('pass')->getCols();
                if(2==$rows[0]){
			return true;
		}
		return false;
	}

	public static function getList($class, $related_id){
		return Reviewer::getList(array('class'=>$class, 'related_id'=>$related_id));
	}

	public static function getLastError(){
		return self::$lastError;
	}

	public static function flow2txt($pass=false){
		static $sets = array(0=>'未审批', '审批通过', '审批失败');
		if($pass===false) return $sets;
		return isset($sets[$pass]) ? $sets[$pass] : false;
	}

	protected static function updateFlow($class, $related_id, $audit_flow){
		$ary = Reviewer::supports();
		$res = call_user_func( array($ary[$class], 'updateFlow'), $related_id, $audit_flow, $class );
		if(!$res){
			if(is_callable( array($ary[$class], 'getError') )){
				self::setError( call_user_func(array($ary[$class], 'getError')) );
			}
			return false;
		}
		return true;
	}

	public static function validClass($class){
		$ary = Reviewer::supports();
		return isset($ary[$class]);
	}

	protected static function setError($msg){
		self::$lastError = $msg;
		return false;
	}

	/**
	 * 需求审批人看到的需求列表
	 */
	public static function getDemandByUser($user_id, $where='', $s=0, $l=null){
		return self::getByUser('_Demand', Reviewer::CLS_DEMAND, $user_id, $where, $s, $l);
	}
	public static function getDemandCountByUser($user_id, $where=''){
		return self::getCountByUser('_Demand', Reviewer::CLS_DEMAND, $user_id, $where);
	}

	/**
	 * 订单审批人看到的订单列表
	 */
	public static function getIndentByUser($user_id, $where='', $s=0, $l=null){
		return self::getByUser('Indent', Reviewer::CLS_INDENT, $user_id, $where, $s, $l);
	}
	public static function getIndentCountByUser($user_id, $where=''){
		return self::getCountByUser('Indent', Reviewer::CLS_INDENT, $user_id, $where);
	}

	/**
	 * 需求审批人看到的领料需求列表
	 */
	public static function getOutDemandByUser($user_id, $where='', $s=0, $l=null){
		return self::getByUser('_Bound', Reviewer::CLS_OUTDEMAND, $user_id, $where, $s, $l);
	}
	public static function getOutDemandCountByUser($user_id, $where=''){
		return self::getCountByUser('_Bound', Reviewer::CLS_OUTDEMAND, $user_id, $where);
	}

	/**
	 * 采购入库质检
	 */
	public static function getQcByUser($user_id, $where='', $s=0, $l=null){
		return self::getByUser('_Bound', Reviewer::CLS_QC, $user_id, $where, $s, $l);
	}
	public static function getQcCountByUser($user_id, $where=''){
		return self::getCountByUser('_Bound', Reviewer::CLS_QC, $user_id, $where);
	}
	
//	/**
//	 * 质检入库审批人
//	 */
//	public static function getIndentConfirmByUser($user_id, $where='', $s=0, $l=null){
//		return self::getByUser('_Bound', Reviewer::CLS_OUTDEMAND, $user_id, $where, $s, $l);
//	}
	
	private static function getByUser($model, $class, $user_id, $where='', $s=0, $l=null){
		$where = "t1.user_id={$user_id}". ($where? " AND ({$where})" : '');
		return Db::get($model)->select('t0.*, t1.id AS r_id, t1.addtime AS r_addtime, t1.pass AS r_pass, t1.remark AS r_remark')
				->join('Reviewer')->on('t1.related_id=t0.id AND t1.class='.$class)
				->where($where)->limit($s, $l)
				->order('t0.id DESC')->getAll();
	}
	
	private static function getCountByUser($model, $class, $user_id, $where=''){
		$where = "t1.user_id={$user_id}". ($where? " AND ({$where})" : '');
		return Db::get($model)->count()
				->join('Reviewer')->on('t1.related_id=t0.id AND t1.class='.$class)
				->where($where)->getCol();
	}
        
        /**
	 * 需求审批反馈
	 */
        public static function getFeedback()
        {
            $tmp = Db::get('_demand')->select('id,audit_flow,sno,reviewer_addtime,type,amount')->where(
                         "audit_flow>0 AND isview='no' AND user_id=".UID
                    )->getAll();
            $output = array();
            if($tmp)
            {
                foreach($tmp as $row)
                {                    
                    $output[] = array(
                                        'id'	=> $row['id'],		
                                        'sno'	=> $row['sno'],
					'time'	=> date('m/d H:i', $row['reviewer_addtime']),
					'message'	=> sprintf('%s - 共计%d件材料',
									DemandHelper::type2text($row['type']),
									$row['amount']),
					'audit_flow'	=> ($row['audit_flow']==1)?'<b style="color:blue">审核通过</b>':'<b style="color:red">审核未通过</b>',
                                        'url'   =>url('proc-view/id/'.$row['id'])
					);
                }
            }
            return $output;
            
        }

        /**
	 * 需求审批提醒
	 */
	public static function getReminders(){
		$list = Reviewer::getList(array('user_id'=>UID, 'pass'=>0), 'id DESC');
                 
                
                
		$supports = Reviewer::supports();
		$output = array(); $i=0;
		if($list) foreach($list as $r){
                       if(!self::nohaspass($r['class'], $r['related_id']) && self::getCursor($r['class'], $r['related_id'])==UserAuthHelper::uid()) //去除审批不通过的以及不是当前审核人的
                       {
			$row = Db::get($supports[$r['class']])->select()->where(array('id'=>$r['related_id']))->getOne();
			switch($r['class']){
			case Reviewer::CLS_DEMAND:
                            	$output[] = array(
					'user'	=> User::getName($row['user_id']),
					'time'	=> date('m/d H:i', $row['addtime']),
					'message'	=> sprintf('%s - %s - 共计%d件材料',
									Dept::getTitle($row['dept_id']),
									DemandHelper::type2text($row['type']),
									$row['amount'] ),
					'type'	=> '需求审批',
					);
                          	break;
			case Reviewer::CLS_INDENT:
				$output[] = array(
					'user'	=> User::getName($row['user_id']),
					'time'	=> date('m/d H:i', $row['addtime']),
					'message'	=> sprintf('供应商 %s，金额 %s元',
									$row['supplier'], fnum($row['total']) ),
					'type'	=> '订单审批',
					);
				break;
			case Reviewer::CLS_QC:
				$output[] = array(
					'user'	=> User::getName($row['user_id']),
					'time'	=> date('m/d H:i', $row['addtime']),
					'message'	=> sprintf('单号 %s，质检三方 %s，共计%d件材料', $row['sno'],
							join(',',UserHelper::getNamesByIds(explode(',',$row['reviewers']))),
							Db::get('BoundItems')->count()->where(array('bound_id'=>$row['id']))->getCol()
						),
					'type'	=> '质检确认',
					);
				break;
			case Reviewer::CLS_OUTDEMAND:
				$output[] = array(
					'user'	=> User::getName($row['user_id']),
					'time'	=> date('m/d H:i', $row['addtime']),
					'message'	=> sprintf('单号 %s，共计%d件材料', $row['sno'],
								Db::get('BoundItems')->count()->where(array('bound_id'=>$row['id']))->getCol()  ),
					'type'	=> '领料审批',
					);
				break;
			}
			$output[$i++]['url'] = url("rever-flag/id/{$r['related_id']}/type/{$r['class']}");
                       }
		}

		return $output;
	}
}
?>